border-bottom: 1px solid var(--border-color-medium, rgba(0, 0, 0, 0.1));
}
+.Dashboard .table {
+ width: auto;
+ text-align: left;
+}
+
[data-darkmode="true"] {
/* invert black SVG line drawings in dark mode */
- .Dashboard .svgmonotone {
+ .Dashboard
+ .svgmonotone {
filter: invert(.5);
}
}
params: [],
- load: function() {
+ load() {
return Promise.all([
network.getWANNetworks(),
network.getWAN6Networks(),
]);
},
- renderHtml: function(data, type) {
+ renderRow(title, value, className = '', tag = 'p') {
+ return E(tag, { 'class': 'mt-2' }, [
+ E('span', {}, [ title + ':' ]),
+ E('span', { 'class': className }, [ value ])
+ ]);
+ },
+
+ renderArrayAsTable(title, values) {
+ const table = E('table', { 'class': 'table' });
+
+ if (Array.isArray(values) && values.length > 0) {
+ values.forEach((val) => {
+ table.appendChild(E('tr', {}, [
+ E('td', {}, [ title + ':' ]),
+ E('td', {}, [ val ])
+ ]));
+ });
+ } else {
+ table.appendChild(E('tr', {}, [
+ E('td', {}, [ title + ':' ]),
+ E('td', {}, [ '-' ])
+ ]));
+ }
+
+ return table;
+ },
+
+ renderHtml(data, type) {
- var icon = type;
- var title = 'router' == type ? _('System') : _('Internet');
- var container_wapper = E('div', { 'class': type + '-status-self dashboard-bg box-s1'});
- var container_box = E('div', { 'class': type + '-status-info'});
- var container_item = E('div', { 'class': 'settings-info'});
+ let icon = type;
+ const title = 'router' == type ? _('System') : _('Internet');
+ const container_wapper = E('div', { 'class': type + '-status-self dashboard-bg box-s1'});
+ const container_box = E('div', { 'class': type + '-status-info'});
+ const container_item = E('div', { 'class': 'settings-info'});
if ('internet' == type) {
icon = (data.v4.connected.value || data.v6.connected.value) ? type : 'not-internet';
container_box.appendChild(E('hr'));
if ('internet' == type) {
- var container_internet_v4 = E('div');
- var container_internet_v6 = E('div');
+ const container_internet_v4 = E('div');
+ const container_internet_v6 = E('div');
- for(var idx in data) {
+ for(let idx in data) {
- for(var ver in data[idx]) {
- var classname = ver,
- suppelements = '',
- visible = data[idx][ver].visible;
+ for(let ver in data[idx]) {
+ let classname = ver;
+ const visible = data[idx][ver].visible;
if('connected' === ver) {
classname = data[idx][ver].value ? 'label label-success' : 'label label-danger';
}
if ('addrsv4' === ver) {
- var addrs = data[idx][ver].value;
+ const addrs = data[idx][ver].value;
if(Array.isArray(addrs) && addrs.length) {
- for(var ip in addrs) {
+ for(let ip in addrs) {
data[idx][ver].value = addrs[ip].split('/')[0];
}
}
}
if (visible) {
- container_internet_v4.appendChild(
- E('p', { 'class': 'mt-2'}, [
- E('span', {'class': ''}, [ data[idx][ver].title + ':' ]),
- E('span', {'class': classname }, [ data[idx][ver].value ]),
- suppelements
- ])
- );
+ if (['dnsv4'].includes(ver) && Array.isArray(data[idx][ver].value)) {
+ container_internet_v4.appendChild(this.renderArrayAsTable(data[idx][ver].title, data[idx][ver].value));
+ } else {
+ container_internet_v4.appendChild(this.renderRow(data[idx][ver].title, data[idx][ver].value, classname));
+ }
}
} else {
}
if (visible) {
- container_internet_v6.appendChild(
- E('p', {'class': 'mt-2'}, [
- E('span', {'class': ''}, [data[idx][ver].title + ':']),
- E('span', {'class': classname}, [data[idx][ver].value]),
- suppelements
- ])
- );
+ if (['dnsv6'].includes(ver) && Array.isArray(data[idx][ver].value)) {
+ container_internet_v6.appendChild(this.renderArrayAsTable(data[idx][ver].title, data[idx][ver].value));
+ } else {
+ container_internet_v6.appendChild(this.renderRow(data[idx][ver].title, data[idx][ver].value, classname));
+ }
}
}
}
container_item.appendChild(container_internet_v4);
container_item.appendChild(container_internet_v6);
} else {
- for(var idx in data) {
+ for(let idx in data) {
container_item.appendChild(
E('p', { 'class': 'mt-2'}, [
E('span', {'class': ''}, [ data[idx].title + ':' ]),
return container_wapper;
},
- renderUpdateWanData: function(data, v6) {
+ renderUpdateWanData(data, v6) {
- var min_metric = 2000000000;
- var min_metric_i = 0;
- for (var i = 0; i < data.length; i++) {
- var metric = data[i].getMetric();
+ let min_metric = 2000000000;
+ let min_metric_i = 0;
+ for (let i = 0; i < data.length; i++) {
+ const metric = data[i].getMetric();
if (metric < min_metric) {
min_metric = metric;
min_metric_i = i;
}
}
- var ifc = data[min_metric_i];
+ const ifc = data[min_metric_i];
if(ifc){
if (v6) {
- var uptime = ifc.getUptime();
+ const uptime = ifc.getUptime();
this.params.internet.v6.uptime.value = (uptime > 0) ? '%t'.format(uptime) : '-';
this.params.internet.v6.ipprefixv6.value = ifc.getIP6Prefix() || '-';
this.params.internet.v6.gatewayv6.value = ifc.getGateway6Addr() || '-';
this.params.internet.v6.dnsv6.value = ifc.getDNS6Addrs() || [ '-' ];
this.params.internet.v6.connected.value = ifc.isUp();
} else {
- var uptime = ifc.getUptime();
+ const uptime = ifc.getUptime();
this.params.internet.v4.uptime.value = (uptime > 0) ? '%t'.format(uptime) : '-';
this.params.internet.v4.protocol.value= ifc.getI18n() || E('em', _('Not connected'));
this.params.internet.v4.gatewayv4.value = ifc.getGatewayAddr() || '0.0.0.0';
}
},
- renderInternetBox: function(data) {
+ renderInternetBox(data) {
this.params.internet = {
return this.renderHtml(this.params.internet, 'internet');
},
- renderRouterBox: function(data) {
+ renderRouterBox(data) {
- var boardinfo = data[2],
- systeminfo = data[3];
+ const boardinfo = data[2];
+ const systeminfo = data[3];
- var datestr = null;
+ let datestr = null;
if (systeminfo.localtime) {
- var date = new Date(systeminfo.localtime * 1000);
+ const date = new Date(systeminfo.localtime * 1000);
datestr = '%04d-%02d-%02d %02d:%02d:%02d'.format(
date.getUTCFullYear(),
return this.renderHtml(this.params.router, 'router');
},
- render: function(data) {
+ render(data) {
return [this.renderInternetBox(data), this.renderRouterBox(data)];
}
});
params: {},
- load: function() {
+ load() {
return Promise.all([
callLuciDHCPLeases(),
network.getDevices()
]);
},
- renderHtml: function() {
+ renderHtml() {
- var container_wapper = E('div', { 'class': 'router-status-lan dashboard-bg box-s1' });
- var container_box = E('div', { 'class': 'lan-info devices-list' });
+ const container_wapper = E('div', { 'class': 'router-status-lan dashboard-bg box-s1' });
+ const container_box = E('div', { 'class': 'lan-info devices-list' });
container_box.appendChild(E('div', { 'class': 'title'}, [
E('img', {
'src': L.resource('view/dashboard/icons/devices.svg'),
E('h3', this.title)
]));
- var container_devices = E('table', { 'class': 'table assoclist devices-info' }, [
+ const container_devices = E('table', { 'class': 'table assoclist devices-info' }, [
E('tr', { 'class': 'tr dashboard-bg' }, [
E('th', { 'class': 'th nowrap' }, _('Hostname')),
E('th', { 'class': 'th' }, _('IP Address')),
])
]);
- for(var idx in this.params.lan.devices) {
- var device = this.params.lan.devices[idx];
+ for(let idx in this.params.lan.devices) {
+ const device = this.params.lan.devices[idx];
container_devices.appendChild(E('tr', { 'class': 'tr cbi-rowstyle-1'}, [
return container_wapper;
},
- renderUpdateData: function(data, leases) {
+ renderUpdateData(data, leases) {
- for(var item in data) {
+ for(let item in data) {
if (/lan|br-lan/ig.test(data[item].ifname) && (typeof data[item].dev == 'object' && !data[item].dev.wireless)) {
- var lan_device = data[item];
- var ipv4addr = lan_device.dev.ipaddrs.toString().split('/');
+ const lan_device = data[item];
+ const ipv4addr = lan_device.dev.ipaddrs.toString().split('/');
this.params.lan.ipv4 = ipv4addr[0] || '?';
this.params.lan.ipv6 = ipv4addr[0] || '?';
}
}
- var devices = [];
- leases.map(function(lease) {
+ const devices = [];
+ leases.map(lease => {
devices[lease.expires] = {
hostname: lease.hostname || '?',
ipv4: lease.ipaddr || '-',
this.params.lan.devices = devices;
},
- renderLeases: function(data) {
+ renderLeases(data) {
- var leases = Array.isArray(data[0].dhcp_leases) ? data[0].dhcp_leases : [];
+ const leases = Array.isArray(data[0].dhcp_leases) ? data[0].dhcp_leases : [];
this.params.lan = {
ipv4: {
return this.renderHtml();
},
- render: function(data) {
+ render(data) {
if (L.hasSystemFeature('dnsmasq') || L.hasSystemFeature('odhcpd'))
return this.renderLeases(data);
params: [],
- load: function() {
+ load() {
return Promise.all([
network.getWifiDevices(),
network.getWifiNetworks(),
network.getHostHints()
- ]).then(function(radios_networks_hints) {
- var tasks = [];
+ ]).then(radios_networks_hints => {
+ const tasks = [];
- for (var i = 0; i < radios_networks_hints[1].length; i++)
- tasks.push(L.resolveDefault(radios_networks_hints[1][i].getAssocList(), []).then(L.bind(function(net, list) {
- net.assoclist = list.sort(function(a, b) { return a.mac > b.mac });
+ for (let i = 0; i < radios_networks_hints[1].length; i++)
+ tasks.push(L.resolveDefault(radios_networks_hints[1][i].getAssocList(), []).then(L.bind((net, list) => {
+ net.assoclist = list.sort((a, b) => { return a.mac > b.mac });
}, this, radios_networks_hints[1][i])));
- return Promise.all(tasks).then(function() {
+ return Promise.all(tasks).then(() => {
return radios_networks_hints;
});
});
},
- renderHtml: function() {
+ renderHtml() {
- var container_wapper = E('div', { 'class': 'router-status-wifi dashboard-bg box-s1' });
- var container_box = E('div', { 'class': 'wifi-info devices-list' });
- var container_radio = E('div', { 'class': 'settings-info' });
- var container_radio_item;
+ const container_wapper = E('div', { 'class': 'router-status-wifi dashboard-bg box-s1' });
+ const container_box = E('div', { 'class': 'wifi-info devices-list' });
+ const container_radio = E('div', { 'class': 'settings-info' });
+ let container_radio_item;
container_box.appendChild(E('div', { 'class': 'title'}, [
E('img', {
E('h3', this.title)
]));
- for (var i =0; i < this.params.wifi.radios.length; i++) {
+ for (let i = 0; i < this.params.wifi.radios.length; i++) {
container_radio_item = E('div', { 'class': 'radio-info' })
- for(var idx in this.params.wifi.radios[i]) {
- var classname = idx,
- radio = this.params.wifi.radios[i];
+ for(let idx in this.params.wifi.radios[i]) {
+ let classname = idx;
+ const radio = this.params.wifi.radios[i];
if (!radio[idx].visible) {
continue;
container_box.appendChild(container_radio);
- var container_devices = E('table', { 'class': 'table assoclist devices-info' }, [
+ const container_devices = E('table', { 'class': 'table assoclist devices-info' }, [
E('tr', { 'class': 'tr dashboard-bg' }, [
E('th', { 'class': 'th nowrap' }, _('Hostname')),
E('th', { 'class': 'th' }, _('SSID')),
])
]);
- for (var i =0; i < this.params.wifi.devices.length; i++) {
- var container_devices_item = E('tr', { 'class': 'tr cbi-rowstyle-1' });
+ for (let i = 0; i < this.params.wifi.devices.length; i++) {
+ const container_devices_item = E('tr', { 'class': 'tr cbi-rowstyle-1' });
- for(var idx in this.params.wifi.devices[i]) {
- var device = this.params.wifi.devices[i];
+ for(let idx in this.params.wifi.devices[i]) {
+ const device = this.params.wifi.devices[i];
if (!device[idx].visible) {
continue;
}
- var container_content;
+ let container_content;
if ('progress' == idx) {
container_content = E('div', { 'class' : 'td device-info' }, [
return container_wapper;
},
- renderUpdateData: function(radios, networks, hosthints) {
+ renderUpdateData(radios, networks, hosthints) {
- for (var i = 0; i < radios.sort(function(a, b) { a.getName() > b.getName() }).length; i++) {
- var network_items = networks.filter(function(net) { return net.getWifiDeviceName() == radios[i].getName() });
+ for (let i = 0; i < radios.sort((a, b) => { a.getName() > b.getName() }).length; i++) {
+ const network_items = networks.filter(net => { return net.getWifiDeviceName() == radios[i].getName() });
- for (var j = 0; j < network_items.length; j++) {
- var net = network_items[j],
- is_assoc = (net.getBSSID() != '00:00:00:00:00:00' && net.getChannel() && !net.isDisabled()),
- chan = net.getChannel(),
- freq = net.getFrequency(),
- rate = net.getBitRate();
+ for (let j = 0; j < network_items.length; j++) {
+ const net = network_items[j];
+ const is_assoc = (net.getBSSID() != '00:00:00:00:00:00' && net.getChannel() && !net.isDisabled());
+ const chan = net.getChannel();
+ const freq = net.getFrequency();
+ const rate = net.getBitRate();
- this.params.wifi.radios.push(
+ this.params.wifi.radios.push(
{
ssid : {
title: _('SSID'),
}
}
- for (var i = 0; i < networks.length; i++) {
- for (var k = 0; k < networks[i].assoclist.length; k++) {
- var bss = networks[i].assoclist[k],
- name = hosthints.getHostnameByMACAddr(bss.mac);
+ for (let i = 0; i < networks.length; i++) {
+ for (let k = 0; k < networks[i].assoclist.length; k++) {
+ const bss = networks[i].assoclist[k];
+ const name = hosthints.getHostnameByMACAddr(bss.mac);
- var progress_style;
- var defaultNF = -90; // default noise floor for devices that do not report it
- var defaultCeil = -30;
- // var q = Math.min((bss.signal + 110) / 70 * 100, 100);
- var q = 100 * ((bss.signal - (bss.noise ? bss.noise: defaultNF) ) / (defaultCeil - (bss.noise ? bss.noise : defaultNF)));
+ let progress_style;
+ const defaultNF = -90; // default noise floor for devices that do not report it
+ const defaultCeil = -30;
+ // const q = Math.min((bss.signal + 110) / 70 * 100, 100);
+ const q = 100 * ((bss.signal - (bss.noise ? bss.noise: defaultNF) ) / (defaultCeil - (bss.noise ? bss.noise : defaultNF)));
if (q == 0 || q < 25)
progress_style = 'bg-danger';
}
},
- render: function(data) {
+ render(data) {
this.params.wifi = {
radios: [],
}));
function invokeIncludesLoad(includes) {
- var tasks = [], has_load = false;
+ const tasks = [];
+ let has_load = false;
- for (var i = 0; i < includes.length; i++) {
+ for (let i = 0; i < includes.length; i++) {
if (typeof(includes[i].load) == 'function') {
- tasks.push(includes[i].load().catch(L.bind(function() {
+ tasks.push(includes[i].load().catch(L.bind(() => {
this.failed = true;
}, includes[i])));
}
function startPolling(includes, containers) {
- var step = function() {
- return network.flushCache().then(function() {
+ const step = () => {
+ return network.flushCache().then(() => {
return invokeIncludesLoad(includes);
- }).then(function(results) {
- for (var i = 0; i < includes.length; i++) {
- var content = null;
+ }).then(results => {
+ for (let i = 0; i < includes.length; i++) {
+ let content = null;
if (includes[i].failed)
continue;
}
}
- var ssi = document.querySelector('div.includes');
+ const ssi = document.querySelector('div.includes');
if (ssi) {
ssi.style.display = '';
ssi.classList.add('fade-in');
});
};
- return step().then(function() {
+ return step().then(() => {
poll.add(step);
});
}
return view.extend({
- load: function() {
- return L.resolveDefault(fs.list('/www' + L.resource('view/dashboard/include')), []).then(function(entries) {
- return Promise.all(entries.filter(function(e) {
+ load() {
+ return L.resolveDefault(fs.list('/www' + L.resource('view/dashboard/include')), []).then(entries => {
+ return Promise.all(entries.filter(e => {
return (e.type == 'file' && e.name.match(/\.js$/));
- }).map(function(e) {
+ }).map(e => {
return 'view.dashboard.include.' + e.name.replace(/\.js$/, '');
- }).sort().map(function(n) {
+ }).sort().map(n => {
return L.require(n);
}));
});
},
- render: function(includes) {
- var rv = E([]), containers = [];
+ render(includes) {
+ const rv = E([]);
+ const containers = [];
- for (var i = 0; i < includes.length - 1; i++) {
+ for (let i = 0; i < includes.length - 1; i++) {
- var container = E('div', { 'class': 'section-content' });
+ const container = E('div', { 'class': 'section-content' });
rv.appendChild(E('div', { 'class': 'cbi-section-' + i, 'style': 'display:none' }, [
container
containers.push(container);
}
- return startPolling(includes, containers).then(function() {
+ return startPolling(includes, containers).then(() => {
return rv;
});
},